package com.ruiyi.subway.utils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.List;

import org.apache.commons.lang.StringUtils;

/**
 * 
 * <p>Title : DateHelper.java </p>
 * <p>Description  日期操作助手类 </p>
 */
public final class DateUtils{

	/**
	 * 按照yyyy-MM-dd格式获取当前日期
	 * 
	 * @return
	 */
	public static Date getDate(){
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		try {
			return dateFormat.parse(dateFormat.format(new Date()));
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 按照yyyy-MM-dd HH:mm:ss的格式获取系统当前时间
	 * 
	 * @param format
	 * @param date
	 */
	public static Date getTime(){
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			return dateFormat.parse(dateFormat.format(new Date()));
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 按照yyyy-MM-dd HH:mm:ss的格式获取系统当前时间
	 * 
	 * @param format
	 * @param date
	 */
	public static Date getTime(String date){
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try {
			return dateFormat.parse(date);
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 按照指定格式将字符串转换为日期
	 * 
	 * @param format
	 * @param date
	 */
	public static Date getDate(String format, String source){
		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
		try {
			if (StringUtils.isNotEmpty(source)){
				return dateFormat.parse(source);
			} else{
				return null;
			}
		} catch (ParseException e) {
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 将yyyy-MM-dd格式的字符串转换为日期类型
	 * 
	 * @param source
	 * @return
	 */
	public static Date getDate(String source){
		if (source != null){
			return getDate("yyyy-MM-dd", source);
		} else{
			return null;
		}
	}
	
	/**
	 * 将日期转换为字符串类型
	 * 
	 * @return
	 */
	public static String date2Char(Date date){
		try{
			if (date != null){
				SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
				return format.format(date);
			}
		} catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 将日期转换为字符串类型的时间
	 * 
	 * @return
	 */
	public static String time2Char(Date date){
		try{
			if (date != null){
				SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				return format.format(date);
			}
		} catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 将日期转换为字符串类型的时间
	 * 
	 * @return
	 */
	public static String time2Char2(Date date){
		try{
			if (date != null){
				SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日HH点mm分");
				return format.format(date);
			}
		} catch (Exception e){
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 获取两个日期相差的天数
	 * 
	 * @param date1 起始日期
	 * @param date2 截止日期
	 * @return
	 */
	public static Integer getDays(Date start, Date end){
		try{
			if (start == null || end == null){
				return null;
			}
			int days = (int)((end.getTime() - start.getTime()) / (60000 * 60 * 24));
			return days;
		} catch (Exception e){
			e.printStackTrace();
			throw new RuntimeException("get days is error");
		}
	}
	
	/**
	 * 获取日期之间相隔几个月
	 * @param start
	 * @param end
	 * @return
	 */
	public static int getBetweenMonths(Date start,Date end){
		//第一步看相隔多少年
		Calendar startTime = Calendar.getInstance();
		startTime.setTime(start);
		Calendar endTime = Calendar.getInstance();
		endTime.setTime(end);
		int startYear=startTime.get(Calendar.YEAR);
		int endYear=endTime.get(Calendar.YEAR);
		int startMonth=startTime.get(Calendar.MONTH);
		int endMonth=endTime.get(Calendar.MONTH);
		int startDay=startTime.get(Calendar.DATE);
		int endDay=endTime.get(Calendar.DATE);
		if(end.getTime()<start.getTime()){
			return 0;
		}else{
			int n=(endYear-startYear)*12+(endMonth-startMonth);
			n=endDay<startDay?(n-1):n;
			return n;
		}
	}
	
	/**
	 * 获取日期间除去正月后，还剩多少天
	 * @param start
	 * @param end
	 * @return
	 */
	public static long getBetweenDaysOffMonth(Date start, Date end){
		int betweenMonth=getBetweenMonths(start,end);
		Calendar startTime = Calendar.getInstance();
		startTime.setTime(start);
		startTime.add(Calendar.MONTH, betweenMonth);
		long n=getOverDayNum(startTime.getTime(), end);
		return n<0?0:n;
	}
	
	/**
	 * 获取两个日期相差的天数
	 * 
	 * @param date1 起始日期
	 * @param date2 截止日期
	 * @return
	 */
	public static Integer getBetweenHours(Date start, Date end){
		try{
			if (start == null || end == null){
				return 0;
			}
			if(end.getTime()<=start.getTime()){
				return 0;
			}
			int hours = (int)((end.getTime() - start.getTime()) / (1000 * 60*60));
			return hours;
		} catch (Exception e){
			e.printStackTrace();
			throw new RuntimeException("getBetweenHours is error");
		}
	}
	
	/**
	 * 按照指定的格式返回当前日期的字符串表是形式
	 * 
	 * @param format
	 * @return
	 */
	public static String getDateForChar(String format){
		try{
			SimpleDateFormat dateFormat = new SimpleDateFormat(format);
			return dateFormat.format(new Date());
		} catch (Exception e){
			e.printStackTrace();
			return null;
		}
	}
	
	/**
	 * 按照yyyy-MM-dd格式返回当前日期的字符串表是形式
	 * 
	 * @return
	 */
	public static String getDateForChar(){
		return getDateForChar("yyyy-MM-dd");
	}
	
	public static Date addHours(Date source,int hours){
		long sourceTime = source.getTime();
		long endTime = sourceTime+hours*3600*1000;
		Date end = new Date(endTime);
		return end;
	}
	
	/**
	 * 为原日期添加指定的天数并返回添加后的日期，如果天数为负数则在原日期的基础上减去指定的天数
	 * 
	 * @param source
	 * @param days
	 * @return
	 */
	public static Date addDays(Date source, int days){
		try{
			Calendar calendar = Calendar.getInstance();
			calendar.setTime(source);
			calendar.add(Calendar.DAY_OF_YEAR, days);
			return calendar.getTime();
		} catch (Exception e){
			throw new RuntimeException("add days is error.");
		}
	}
	
	/**
	 * 为原日期添加指定的年数并返回添加后的日期，如果年数为负数则在原日期的基础上减去指定的年数
	 * 
	 * @param source
	 * @param days
	 * @return
	 */
	public static Date addYear(Date source, int year){
		try{
			SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
			format.parse(format.format(source));
			Calendar calendar = format.getCalendar();
			calendar.add(Calendar.YEAR, year);
			return calendar.getTime();
		} catch (Exception e){
			throw new RuntimeException("add days is error.");
		}
	}

	/**
     * 取出剩余天数
     * 
     * @param startDate 开始时间
     * @param overDate 结束时间
     * @return day 
     */
    public static long getOverDayNum(Date startDate,Date overDate)
    {
        long day=0;
        day=overDate.getTime()-startDate.getTime();
        day=day / 1000 / 60 / 60 / 24;
        
        return day<0?0:day;
    }
    
    /**
     * 取出当前年
     * @return
     */
    public static String getYear(){
    	Calendar cal = Calendar.getInstance();
		Integer year = cal.get(Calendar.YEAR);
    	return year.toString();
    }
    
    /**
     * 取出当前月
     * @return
     */
    public static String getMonth(){
    	Calendar cal = Calendar.getInstance();
    	Integer month = cal.get(Calendar.MONTH )+1;
    	return month<10?"0"+month : month.toString();
    }
    
    /**
     * 取出当前日
     * @return
     */
    public static String getDayOfMonth(){
    	Calendar cal = Calendar.getInstance();
    	Integer day = cal.get(Calendar.DAY_OF_MONTH);
    	return day<10?"0"+day : day.toString();
    }
    
    /**
     * 取得指定日期为星期几 
     * @param date
     * @return 返回1是星期日、2是星期一、3是星期二、4是星期三、5是星期四、6是星期五、7是星期六
     */
    public static int getDayofWeek(Date date){  
    	  Calendar cal = Calendar.getInstance();  
    	  cal.setTime(date);  
    	  return cal.get(Calendar.DAY_OF_WEEK);  
   }
    
    /**
     * 返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此 Date 对象表示的毫秒数
     * @return
     */
    public static String getTimeNum(){
    	return new Long(new Date().getTime()).toString();
    }
    
    /**
     * 取两个日期之间的所有日期
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @return
     * @throws ParseException
     */
    public static List<Date> getBetweenDate(String startDate,String endDate) throws ParseException  
    {  
        List<Date> list=new ArrayList<Date>();  
        SimpleDateFormat  sdf=new SimpleDateFormat("yyyy-MM");  
        GregorianCalendar gc1=new GregorianCalendar(),gc2=new GregorianCalendar();  
        gc1.setTime(sdf.parse(startDate));  
        gc2.setTime(sdf.parse(endDate));  
        do{  
            GregorianCalendar gc3=(GregorianCalendar)gc1.clone();  
            String DateStr=gc3.get(Calendar.YEAR)+"-"+(gc3.get(Calendar.MONTH)+1)+"- "+  gc3.get(Calendar.DAY_OF_MONTH);
            list.add(getDate(DateStr));  
            gc1.add(Calendar.DAY_OF_MONTH, 1);               
         }while(!gc1.after(gc2));  
        return list;  
    }
    /**
     * 为日期添加月份
     * @param data
     * @param month
     * @return
     */
    public static Date addMonth(Date day,int month){
    	 Calendar calendar = new GregorianCalendar(); 
         calendar.setTime(day); 
         calendar.add(Calendar.MONTH,month);
         return calendar.getTime();
    }
    
    /**
     * 将日期增加天数
     * @param date
     * @param dayNum
     * @return
     */
    public static Date dateAddDay(Date date,int dayNum){
         Calendar calendar = new GregorianCalendar(); 
         calendar.setTime(date); 
         calendar.add(calendar.DATE,dayNum);//把日期往后增加一天.整数往后推,负数往前移动 
         date=calendar.getTime();   //这个时间就是日期往后推一天的结果 
         return date;
    }
    
    /**
     * 将日期减天数
     * @param date
     * @param dayNum
     * @return
     */
    public static Date dateDecDay(Date date,int dayNum){
         Calendar calendar = new GregorianCalendar(); 
         calendar.setTime(date); 
         calendar.add(calendar.DATE,-dayNum);//把日期往后增加一天.整数往后推,负数往前移动 
         date=calendar.getTime();   //这个时间就是日期往后推一天的结果 
         return date;
    }
    
    /**
     * 取两个时间之间的豪秒数
     * @return
     */
    public static Long getBetweenMillis(Date startTime,Date endTime){
    	Long i= endTime.getTime()-startTime.getTime();
    	return i;
    }
    
    public static String getNearHoliday(){
    	String[] gljr={"01-01","02-14","03-08","05-01","06-01","09-10","12-25"};//
    	String[] gljrms={"元旦","情人节","妇女节","劳动节","儿童节","教师节","圣诞节"} ;
    	String[] yljr={"01-01","01-15","05-05","07-07","08-15","09-09","12-30"};
    	String[] yljrms={"春节","元宵节","端午节","情人节","中秋节","重阳节","除夕"} ;  	
    	Calendar cal=Calendar.getInstance();
    	Date date = cal.getTime();
    	//获取最近的阳历节日
    	long min_gl=365;
    	int min_gl_index=0;
    	for(int i=0;i<gljr.length;i++){
    		String jr=gljr[i];
    		jr=cal.get(Calendar.YEAR)+"-"+jr;
    		Date jrDate=getDate(jr);
    		System.out.println(jr);
    		long l=getOverDayNum(date, jrDate);
    		if(l<min_gl&&l>0) {
    			min_gl=l; 
    			min_gl_index=i;
    		}
    	}
    	//获取最近的农历节日
    	long min_yl=365;
    	int min_yl_index=0;
    	for(int i=0;i<yljr.length;i++){		
    		String jr=yljr[i];
    		jr=cal.get(Calendar.YEAR)+"-"+jr;
    		System.out.println(jr);
    		Date jrDate=LunarSolarConverter.LunarToSolarDate(jr);    		
    		long l=getOverDayNum(date, jrDate);
    		if(l<min_yl&&l>0) {
    			min_yl=l; 
    			min_yl_index=i;
    		}
    	}
    	if(min_gl<min_yl){
    		return "离"+gljrms[min_gl_index]+"还有"+min_gl+"天";
    	}else{
    		return "离"+yljrms[min_yl_index]+"还有"+min_yl+"天";
    	}
    	
    }
    
    /**
     * 获取时间段内，月份的起始时间
     * 一月起始时间：上月28-本月28
     * @param startTime
     * @param endTime
     * @return
     */
    public static List<HashMap<String,Date>> 
                           getBetweenMonthTime(Date startTime, Date endTime){
    	List<HashMap<String,Date>> list = new ArrayList<HashMap<String,Date>>();
    	int betweenMonth=getBetweenMonths(startTime, endTime);
    	
    	Calendar startCal=Calendar.getInstance();
   	    Calendar endCal=Calendar.getInstance();
		Date startMonthDate=null;
   	    Date endMonthDate=null;
	   	 if(startTime.getTime()==endTime.getTime()){
		   	  startCal.setTime(startTime);
			  endCal.setTime(startTime);
		      startCal.add(Calendar.MONTH, -1);
		      startCal.set(Calendar.DAY_OF_MONTH, 28);
			  endCal.set(Calendar.DAY_OF_MONTH, 28);
			  startMonthDate=startCal.getTime();
			  endMonthDate=endCal.getTime();
			  HashMap<String,Date> map = new HashMap<String,Date>();
			  map.put("start_time", startMonthDate);
			  map.put("end_time", endMonthDate);
			  list.add(map);
			  return list;
	 	 }
    	 for(int i=0;i<betweenMonth+1;i++){
    		 HashMap<String,Date> map = new HashMap<String,Date>();   
    		  if(i==0){
    			  startCal.setTime(startTime);
    			  endCal.setTime(startTime);			 
    			  endCal.set(Calendar.DAY_OF_MONTH, 28);
    			  startMonthDate=startCal.getTime();
    			  if(startMonthDate.getTime()>=endCal.getTime().getTime()){
    				  endCal.add(Calendar.MONTH, 1);
    			  }
    			  endMonthDate=endCal.getTime();
    			  map.put("start_time", startMonthDate);
    			  map.put("end_time", endMonthDate);
    			  list.add(map);
    		  }else{
    			  startCal.setTime(endMonthDate);
    			  endCal.setTime(endMonthDate);   			 
    			  endCal.set(Calendar.DAY_OF_MONTH, 28);
    			  endCal.add(Calendar.MONTH, 1);
    			  startMonthDate=startCal.getTime();
    			  endMonthDate=endCal.getTime();
    			  map.put("start_time", startMonthDate);
    			  map.put("end_time", endMonthDate);
    			  list.add(map);
    		  }
    	 }
    	 if(endMonthDate.getTime()<endTime.getTime()){
    		 HashMap<String,Date> map = new HashMap<String,Date>();   
    		  map.put("start_time", endMonthDate);
			  map.put("end_time", endTime);
			  list.add(map);
    	 }
    	 return list;
    }
    
    public static void main(String[] args) throws Exception {  
    	 String start_time="2017-03-20";
    	 String end_time="2017-06-05";
    	 
    	 SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd");
    	 Date start_date=format.parse(start_time);
    	 Date end_date=format.parse(end_time);
         
    	 List<HashMap<String,Date>> list = getBetweenMonthTime(start_date,end_date);
    	 for(HashMap<String,Date> map:list){
    		 String startTime = map.get("start_time").toLocaleString();
    		 String endTime = map.get("end_time").toLocaleString();
    		
    		 System.out.println(startTime+" - "+endTime);
    		 System.out.println("--------------------------------------------------");
    	 }
    }  
}
